package cn.modfun.common.lang;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

/**
 * Jaxb2工具类
 * 
 * @author zhuc
 * @create 2013-3-29 下午2:40:14
 */
public class JaxbUtils {

	/**
	 * xmlToObject
	 * 
	 * @param <T>
	 *            三个T，第一个是定义泛型，第二个是返回的类型，第三个是参数的类型，这三个类型是由参数的类型来决定的。
	 * @param objectClass
	 * @param xml
	 * @return T
	 * @throws JAXBException
	 */
	@SuppressWarnings("unchecked")
	public static <T> T xmlToObject(Class<T> objectClass, String xml) throws JAXBException {
		InputStream inputStream = null;
		Unmarshaller unmarshaller = null;
		JAXBContext jaxbContext = null;

		// 获取JAXBContext的新实例，创建的JAXBContext将识别参数objectClass类 new class[]
		// objectClass.getClass()
		jaxbContext = JAXBContext.newInstance(objectClass);
		// 创建Unmarshaller对象，可以将xml数据转换成java对象
		unmarshaller = jaxbContext.createUnmarshaller();
		// 将字符串或字节数组变成输入流
		inputStream = new ByteArrayInputStream(xml.getBytes());
		// 判断输入流是否为空（调用close()时必须不为空）
		if (inputStream != null) {
			try {
				// 清除输入流内存占用
				inputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		// 解析inputStream，返回对象
		return (T) unmarshaller.unmarshal(inputStream);
	}
	/**
	 * 
	 * @param xml
	 * @param beanClass
	 * @return
	 */
	public static <T> T convertToBean(String xml,Class<T> beanClass){
		try {
			return xmlToObject(beanClass,xml);
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * objectToXml
	 * 
	 * @param object
	 * @param format
	 * @return string
	 * @throws JAXBException
	 */
	public static String objectToXml(Object object, boolean format) throws JAXBException {
		String xml;
		Marshaller marshaller = null;
		JAXBContext jaxbContext = null;
		ByteArrayOutputStream baos = null;

		jaxbContext = JAXBContext.newInstance(object.getClass());
		marshaller = jaxbContext.createMarshaller();

		// 设置输出数据的编码格式(以防乱码)
		marshaller.setProperty("jaxb.encoding", "UTF-8");
		// 设置输出数据的编码格式,System.getProperty("file.encoding")表示格式同调用该方法的最上层的类的编码方式(这里就是main方法的java文件的保存编码)
		// marshaller.setProperty("jaxb.encoding",
		// System.getProperty("file.encoding"));

		// 格式化xml
		marshaller.setProperty("jaxb.formatted.output", format);

		baos = new ByteArrayOutputStream();
		// 将object转换baos(字节数组)
		marshaller.marshal(object, baos);
		// 转换为string类型
		xml = baos.toString();

		if (baos != null) {
			try {
				baos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return xml;
	}
	
	public static void main(String[] args) {
		/*String xml = "<?xml version=\"1.0\"?>"
				+ "<h3c_license_registration_req xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"
				+ "<timeZone>China Standard Time;480;(GMT+08:00) 北京，重庆，香港特别行政区，乌鲁木齐;中国标准时间;中国夏季时间;;</timeZone>"
				+ "<requestTime>2015-03-12 13:56:12</requestTime>" + "<activationType>First</activationType>"
				+ "<pluginActivation>激活时，用户选择的产品分类标识，用于确认激活插件</pluginActivation>" + "<licenseKeys>" + "<licenseKey>"
				+ "<licenseProd>3130A001</licenseProd>" + "<key><![CDATA[3130A001-ANfc:2YS-9Qbq4hj9-Xg:g:d@@]]></key>"
				+ "<LimitTime>365</LimitTime>" + "<consignmentTime>2015-02-10 13:56:17</consignmentTime>"
				+ "<FirstRegisterTime>2015-03-12 13:56:17</FirstRegisterTime>" + "</licenseKey>" + "<licenseKey>"
				+ "<licenseProd>3130A002</licenseProd>" + "<key><![CDATA[3130A002-wbg6J$cG-e2tFCsXq-RmsW7GHn]]></key>"
				+ "<LimitTime>60</LimitTime>" + "<consignmentTime>2015-01-10 10:56:17</consignmentTime>"
				+ "<FirstRegisterTime>2015-03-12 13:56:17</FirstRegisterTime>" + "</licenseKey>" + "</licenseKeys>"
				+ "<deviceInfo>" + "<baseProd></baseProd>" + "<serialNum><![CDATA[2198010001KB09C000034]]></serialNum>"
				+ "<machineID><![CDATA[]]></machineID>" + "<extendedAttribute1></extendedAttribute1>"
				+ "<extendedAttribute2></extendedAttribute2>" + "<extendedAttribute3></extendedAttribute3>"
				+ "<extendedAttribute4></extendedAttribute4>" + "<extendedAttribute5></extendedAttribute5>"
				+ "<deviceFileInfo></deviceFileInfo>" + "</deviceInfo>" + "</h3c_license_registration_req>";
*/
		/*H3cRegisterRequest req;
		try {
			req = xmlToObject(H3cRegisterRequest.class, xml);
		} catch (JAXBException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/

	}
}